package com.gt.quality.utils;


import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSONObject;
import com.gt.quality.base.pojo.LayGradleSelector;
import com.gt.quality.base.pojo.LayerTreeSelect;
import com.gt.quality.system.entity.vo.MenuTreeResponse;
import com.gt.quality.system.entity.vo.MenuTreeVo;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Objects;

@SuppressWarnings("all")
public class CreateTreeUtils {

    /**
     * 构建前端返回的报文对象
     *
     * @param item item
     * @return MenuTreeVo
     */
    public static MenuTreeVo buildMenuTreeVo(Long id, Long parentId, String titleName, String icon) {
        MenuTreeVo menuTreeVo = new MenuTreeVo();
        menuTreeVo.setIcon(StringUtils.isBlank(icon) ? "layui-icon-template" : icon);
        menuTreeVo.setId(id);
        menuTreeVo.setParentId(parentId);
        menuTreeVo.setTitle(titleName);
        menuTreeVo.setSpread(true);
        menuTreeVo.setChecked(false);
        menuTreeVo.setChildren(null);
        return menuTreeVo;
    }


    /**
     * 创建Tree结构。子项为NULL不会包含children:[]
     *
     * @return List
     */
    public static List<MenuTreeVo> createAnyThingTree(List<MenuTreeVo> allListVo) {
        return allListVo.stream().filter(parentNode -> parentNode.getParentId() == null || parentNode.getParentId() == 0)
                .map(node -> getAnyThingChild(node, allListVo)).toList();
    }

    /**
     * String 的结构体
     * 创建Tree结构。子项为NULL依旧包含children:[]
     *
     * @param allListVo allListVo
     * @return List
     */
    public static List<MenuTreeResponse> createTree(List<MenuTreeResponse> allListVo) {
        return allListVo.stream().filter(parentNode -> parentNode.getParentId() == null || parentNode.getParentId().equals("0"))
                .map(node -> getAnyThingChild(node, allListVo)).toList();
    }

    /**
     * 递归辅助函数
     * 1、filter：获取子节点pid是否等于id
     * 2、map：递归获取子节点
     *
     * @param parent  上级节点
     * @param allList 所有数据
     */
    public static MenuTreeVo getAnyThingChild(MenuTreeVo parent, List<MenuTreeVo> allList) {
        List<MenuTreeVo> list = allList.stream()
                .filter(subNode -> Objects.equals(subNode.getParentId(), parent.getId()))
                .map(subNode -> getAnyThingChild(subNode, allList)).toList();
        // 适配LayUI--菜单展示：没有下一级菜单一定一定不要携带 children ,哪怕是children:[] 也不行
        if (CollectionUtil.isNotEmpty(list)) {
            parent.setChildren(list);
        }
        return parent;
    }

    /**
     * String的结构体使用递归辅助函数
     * 1、filter：获取子节点pid是否等于id
     * 2、map：递归获取子节点
     *
     * @param parent  上级节点
     * @param allList 所有数据
     */
    public static MenuTreeResponse getAnyThingChild(MenuTreeResponse parent, List<MenuTreeResponse> allList) {
        List<MenuTreeResponse> list = allList.stream()
                .filter(subNode -> Objects.equals(subNode.getParentId(), parent.getId()))
                .map(subNode -> getAnyThingChild(subNode, allList)).toList();
        // 适配LayUI--菜单展示：没有下一级菜单一定一定不要携带 children ,哪怕是children:[] 也不行
        if (CollectionUtil.isNotEmpty(list)) {
            parent.setChildren(list);
        }
        return parent;
    }

    /**
     * 创建Tree结构。子项为NULL不会包含children:[]
     *
     * @param allListVo allListVo
     * @param pidKey    pidKey
     * @param idKey     idKey
     * @return List
     */
    public static List<JSONObject> createAnyThingTree(List<JSONObject> allListVo, String pidKey, String idKey) {
        return allListVo.stream().filter(parentNode -> parentNode.getLong(pidKey) == null)
                .map(node -> getAnyThingChild(node, allListVo, pidKey, idKey)).toList();
    }

    /**
     * 递归辅助函数
     *
     * @param parent  上级节点
     * @param allList 所有数据
     */
    public static JSONObject getAnyThingChild(JSONObject parent, List<JSONObject> allList, String pidKey, String idKey) {
        /**
         * 1、filter：获取子节点pid是否等于id
         * 2、map：递归获取子节点
         * */
        List<JSONObject> list = allList.stream()
                .filter(subNode -> Objects.equals(subNode.getLong(pidKey), parent.getLong(idKey)))
                .map(subNode -> getAnyThingChild(subNode, allList, pidKey, idKey)).toList();
        // 适配LayUI--菜单展示：没有下一级菜单一定一定不要携带 children ,哪怕是children:[] 也不行
        if (CollectionUtil.isNotEmpty(list)) {
            parent.put("children", list);
        }
        return parent;
    }

    /**
     * 默认创建Tree结构。子项为NULL依旧包含children:[]
     *
     * @param allListVo allListVo
     * @param pidKey    pidKey
     * @param idKey     idKey
     * @return List
     */
    public static List<JSONObject> createTree(List<JSONObject> allListVo, String pidKey, String idKey) {
        return allListVo.stream().filter(parentNode -> parentNode.getLong(pidKey) == null)
                .map(node -> getChildren(node, allListVo, pidKey, idKey)).toList();
    }

    /**
     * 递归辅助函数
     *
     * @param parent  上级节点
     * @param allList 所有数据
     */
    public static JSONObject getChildren(JSONObject parent, List<JSONObject> allList, String pidKey, String idKey) {
        /**
         * 1、filter：获取子节点pid是否等于id
         * 2、map：递归获取子节点
         * */
        List<JSONObject> list = allList.stream()
                .filter(subNode -> Objects.equals(subNode.getLong(pidKey), parent.getLong(idKey)))
                .map(subNode -> getAnyThingChild(subNode, allList, pidKey, idKey)).toList();
        // 适配LayUI--菜单展示：没有下一级菜单一定一定不要携带 children ,哪怕是children:[] 也不行
        parent.put("children", list);
        return parent;
    }


    /**
     * 自定义全属性
     *
     * @param allListVo   allListVo
     * @param pidKey      pidKey
     * @param idKey       idKey
     * @param childrenKey childrenKey
     * @return List
     */
    public static List<JSONObject> createTree(List<JSONObject> allListVo, String pidKey, String idKey, String childrenKey) {
        return allListVo.stream().filter(parentNode -> parentNode.getLong(pidKey) == null)
                .map(node -> getChildren(node, allListVo, pidKey, idKey, childrenKey)).toList();
    }

    /**
     * 递归辅助函数
     *
     * @param parent  上级节点
     * @param allList 所有数据
     */
    public static JSONObject getChildren(JSONObject parent, List<JSONObject> allList, String pidKey, String idKey, String childrenKey) {
        /**
         * 1、filter：获取子节点pid是否等于id
         * 2、map：递归获取子节点
         * */
        List<JSONObject> list = allList.stream()
                .filter(subNode -> Objects.equals(subNode.getLong(pidKey), parent.getLong(idKey)))
                .map(subNode -> getAnyThingChild(subNode, allList, pidKey, idKey)).toList();
        // 适配LayUI--菜单展示：没有下一级菜单一定一定不要携带 children ,哪怕是children:[] 也不行
        parent.put(childrenKey, list);
        return parent;
    }


    public static LayGradleSelector buildSelectTreeVo(Long currentId, Long parentId, String lable) {
        LayGradleSelector layGradleSelector = new LayGradleSelector();
        layGradleSelector.setValue(currentId);
        layGradleSelector.setParentValue(parentId);
        layGradleSelector.setLabel(lable);
        return layGradleSelector;
    }

    public static LayerTreeSelect buildLayerTreeSelect(Long currentId, Long parentId, String lable) {
        LayerTreeSelect layGradleSelector = new LayerTreeSelect();
        layGradleSelector.setId(currentId);
        layGradleSelector.setParentId(parentId);
        layGradleSelector.setTitle(lable);
        layGradleSelector.setField(currentId.toString());
        return layGradleSelector;
    }

    /**
     * 级联多选结构
     *
     * @param treeVoList treeVoList
     */
    public static List<LayGradleSelector> createSelectTree(List<LayGradleSelector> treeVoList) {
        return treeVoList.stream().filter(parentNode -> parentNode.getParentValue() == null || parentNode.getParentValue() == 0)
                .map(node -> getSelectChild(node, treeVoList)).toList();
    }

    /**
     * 级联多选结构
     *
     * @param treeVoList treeVoList
     */
    public static List<LayerTreeSelect> createLayerTreeSelect(List<LayerTreeSelect> treeVoList) {
        return treeVoList.stream().filter(parentNode -> parentNode.getParentId() == null || parentNode.getParentId() == 0)
                .map(node -> getLayerTreeSelectChild(node, treeVoList)).toList();
    }


    /**
     * 递归辅助函数
     * 1、filter：获取子节点pid是否等于id
     * 2、map：递归获取子节点
     *
     * @param parent  上级节点
     * @param allList 所有数据
     */
    public static LayerTreeSelect getLayerTreeSelectChild(LayerTreeSelect parent, List<LayerTreeSelect> allList) {
        List<LayerTreeSelect> list = allList.stream()
                .filter(subNode -> Objects.equals(subNode.getParentId(), parent.getId()))
                .map(subNode -> getLayerTreeSelectChild(subNode, allList)).toList();
        // 适配LayUI--菜单展示：没有下一级菜单一定一定不要携带 children ,哪怕是children:[] 也不行
        if (CollectionUtil.isNotEmpty(list)) {
            parent.setChildren(list);
        }
        return parent;
    }

    /**
     * 递归辅助函数
     * 1、filter：获取子节点pid是否等于id
     * 2、map：递归获取子节点
     *
     * @param parent  上级节点
     * @param allList 所有数据
     */
    public static LayGradleSelector getSelectChild(LayGradleSelector parent, List<LayGradleSelector> allList) {
        List<LayGradleSelector> list = allList.stream()
                .filter(subNode -> Objects.equals(subNode.getParentValue(), parent.getValue()))
                .map(subNode -> getSelectChild(subNode, allList)).toList();
        // 适配LayUI--菜单展示：没有下一级菜单一定一定不要携带 children ,哪怕是children:[] 也不行
        if (CollectionUtil.isNotEmpty(list)) {
            parent.setChildren(list);
        }
        return parent;
    }

    public static MenuTreeResponse buildMenuTreeResponse(Long dictId, Long parentDictId, String dictName, String icon, String dictType) {
        MenuTreeResponse menuTreeVo = new MenuTreeResponse();
        menuTreeVo.setIcon(StringUtils.isBlank(icon) ? "layui-icon-template" : icon);
        menuTreeVo.setId(dictId.toString());
        menuTreeVo.setParentId(parentDictId == null ? "0" : parentDictId.toString());
        menuTreeVo.setTitle(dictName);
        menuTreeVo.setSpread(true);
        menuTreeVo.setChecked(false);
        menuTreeVo.setChildren(null);
        menuTreeVo.setCoreField(dictType);
        return menuTreeVo;
    }
}
